﻿namespace MefContrib.Models.Provider
{
    using System;
    using System.Diagnostics;
    using System.Reflection;

    /// <summary>
    /// Provides an abstraction for working with a type on a reflection level.
    /// </summary>
    public class ComposableType : ComposableMember
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ComposableType"/> class
        /// for the specified <see cref="MemberInfo"/>.
        /// </summary>
        /// <param name="member">The member to make composable.</param>
        public ComposableType(MemberInfo member)
            : base(member)
        {
        }

        /// <summary>
        /// Gets the type of the object which the exportable member belongs to.
        /// </summary>
        /// <value>A <see cref="Type"/> object.</value>
        public override Type DeclaringType
        {
            [DebuggerStepThrough]
            get { return this.ReturnType; }
        }

        /// <summary>
        /// Gets a value indicating whether or not type of the <see cref="ComposableType"/> is of a lazy type or not.
        /// </summary>
        /// <value><see langword="true" /> if it is of a known lazy type; otherwise <see langword="false" />.</value>
        public override bool IsLazyType
        {
            [DebuggerStepThrough]
            get { return false; }
        }

        /// <summary>
        /// Gets a value indicating whether or not a value can be retrieved from the member.
        /// </summary>
        /// <value><see langword="true" /> if a value can be retrieved; otherwise <see langword="false" />.</value>
        public override bool IsReadable
        {
            [DebuggerStepThrough]
            get { return true; }
        }

        /// <summary>
        /// Gets a value indicating whether or not an instance is needed for the value to be retrieved or assigned.
        /// </summary>
        /// <value><see langword="true" /> if an instance is needed; otherwise <see langword="false" />.</value>
        public override bool IsInstanceNeeded
        {
            [DebuggerStepThrough]
            get { return true; }
        }

        /// <summary>
        /// Gets a value indicating whether or not a value can be assigned to the member.
        /// </summary>
        /// <value><see langword="true" /> if a value can be assigned; otherwise <see langword="false" />.</value>
        public override bool IsWritable
        {
            [DebuggerStepThrough]
            get { return false; }
        }

        /// <summary>
        /// Gets the <see cref="Type"/> of the return value of the <see cref="ComposableType"/>.
        /// </summary>
        /// <value>A <see cref="Type"/> object.</value>
        public override Type ReturnType
        {
            [DebuggerStepThrough]
            get { return (Type)this.Member; }
        }

        /// <summary>
        /// Gets the value of the member.
        /// </summary>
        /// <param name="instance">The instance to get the value from.</param>
        /// <returns>The value of the member.</returns>
        /// <exception cref="InvalidOperationException">No function for retrieving the value has been set.</exception>
        public override object GetValue(object instance)
        {
            return instance;
        }
    }
}